﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using chad.azure.diagnostics.data;

using Microsoft.WindowsAzure.Storage;
using Microsoft.WindowsAzure.Storage.Table;

using System.Text.RegularExpressions;

namespace chad.azure.diagnostics.wad
{
    public class TraceDataSourceProcessor
    {
        private String _StorageAccountName = "";
        private String _StorageAccountKey = "";
        private String _DeploymentId = "";
        private String _RoleName = "";
        private String _MessageFilterRegexMatch = "";

        public TraceDataSourceProcessor(String storageAccountName, String storageAccountKey, String deploymentId = null, String roleName = null, String messageFilterRegexMatch = null)
        {
            _StorageAccountName = storageAccountName;
            _StorageAccountKey = storageAccountKey;
            _DeploymentId = deploymentId;
            _RoleName = roleName;
            _MessageFilterRegexMatch = messageFilterRegexMatch;
        }

        public List<Event> GetEvents(DateTime startDateTime, DateTime endDateTime, int eventLevelLessThanOrEqual = -1, int maxEventCount = -1) //, object[] args = null)
        {
            //http://blogs.msdn.com/b/windowsazurestorage/archive/2012/11/06/windows-azure-storage-client-library-2-0-tables-deep-dive.aspx
            const String tableName = "WADLogsTable";

            List<Event> events= new List<Event>();

            CloudStorageAccount storageAccount = CloudStorageAccount.Parse(StorageAccountHelper.GetConnectionString(_StorageAccountName, _StorageAccountKey));
            CloudTableClient tableClient = storageAccount.CreateCloudTableClient();

            tableClient.DefaultRequestOptions.PayloadFormat = TablePayloadFormat.JsonNoMetadata;

            CloudTable table = tableClient.GetTableReference(tableName);

            String startingPartition = WadHelper.GenerateWadPartitionKeyFromUtcDateTime(startDateTime);
            String endingPartition = WadHelper.GenerateWadPartitionKeyFromUtcDateTime(endDateTime);

            IQueryable<TraceLogEntity> query =
                (from p in table.CreateQuery<TraceLogEntity>()
                 where string.Compare(p.PartitionKey, startingPartition) >= 0 &&
                 //p.Level <= eventLevelLessThanOrEqual &&
                 string.Compare(p.PartitionKey, endingPartition) <= 0
                 select p);

            if(eventLevelLessThanOrEqual > -1)
            {
                query = query.Where(q => q.Level <= eventLevelLessThanOrEqual);
            }

            if (_DeploymentId != null)
            {
                query = query.Where(q => q.DeploymentId == _DeploymentId);
            }

            if(_RoleName != null)
            {
                query = query.Where(q => q.Role == _RoleName);
            }

            if(_MessageFilterRegexMatch != null && _MessageFilterRegexMatch != String.Empty)
            {
                query = query.Where(q => Regex.IsMatch(q.Message, _MessageFilterRegexMatch));
            }

            // Has to be the last of the where conditions
            if (maxEventCount > 0)
                query = query.Take(maxEventCount);

            foreach (var p in query.AsEnumerable())
            {
                Event m = new Event();

                m.DeploymentId = p.DeploymentId;
                m.Level = (EventLevel)p.Level;
                m.Message = p.Message;
                m.Source = "Trace";
                m.Channel = "Trace";
                m.EventDateTime = new DateTime(p.EventTickCount);
                m.ObjectIdentifier = p.RoleInstance;
                m.RoleIdentifier = p.Role;
                m.DateTimeTimeZone = "UTC";

                events.Add(m);
            }

            return events;
        }

    }
}
